package com.ruoyi.cs.service.impl;

import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.stream.Collectors;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.domain.Response;
import com.ruoyi.common.core.domain.entity.SysDictData;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.core.redis.RedisLock;
import com.ruoyi.common.exception.CustomException;
import com.ruoyi.common.utils.*;
import com.ruoyi.common.utils.uuid.IdUtils;
import com.ruoyi.cs.domain.*;
import com.ruoyi.cs.domain.vo.ChallengeTGoodsVo;
import com.ruoyi.cs.domain.vo.RedisChallengeTGoods;
import com.ruoyi.cs.mapper.*;
import com.ruoyi.system.mapper.SysConfigMapper;
import com.ruoyi.system.mapper.SysDictDataMapper;
import com.ruoyi.system.service.ISysDictDataService;
import com.ruoyi.system.service.ISysDictTypeService;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.RandomUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Service;
import com.ruoyi.cs.service.ITMineClearService;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import javax.sound.midi.Soundbank;

/**
 * 排雷记录Service业务层处理
 * 
 * @author liuzhisheng
 * @date 2022-12-13
 */
@Service
@SuppressWarnings("all")
public class TMineClearServiceImpl implements ITMineClearService 
{

    private static final Logger log = LoggerFactory.getLogger(TMineClearServiceImpl.class);
    @Autowired
    private TMineClearMapper tMineClearMapper;
    @Autowired
    private TGoodsMapper tGoodsMapper;
    @Autowired
    private TUserMapper tUserMapper;
    @Autowired
    private ISysDictTypeService iSysDictTypeService;
    @Autowired
    private RedisCache redisCache;
    @Autowired
    private RedisLock lock;
    @Autowired
    private TBalanceChangeMapper balanceChangeMapper;
    @Autowired
    private ISysDictDataService iSysDictDataService;
    @Autowired
    private TBackpackMapper tBackpackMapper;
    @Autowired
    private SysConfigMapper sysConfigMapper;
    /**
     * 查询排雷记录
     * 
     * @param id 排雷记录主键
     * @return 排雷记录
     */
    @Override
    public TMineClear selectTMineClearById(String id)
    {
        return tMineClearMapper.selectTMineClearById(id);
    }

    /**
     * 查询排雷记录列表
     * 
     * @param tMineClear 排雷记录
     * @return 排雷记录
     */
    @Override
    public List<TMineClear> selectTMineClearList(TMineClear tMineClear)
    {
        return tMineClearMapper.selectTMineClearList(tMineClear);
    }

    /**
     * 新增排雷记录
     * 
     * @param tMineClear 排雷记录
     * @return 结果
     */
    @Override
    public int insertTMineClear(TMineClear tMineClear)
    {
        tMineClear.setCreateTime(DateUtils.getNowDate());
        return tMineClearMapper.insertTMineClear(tMineClear);
    }

    /**
     * 修改排雷记录
     * 
     * @param tMineClear 排雷记录
     * @return 结果
     */
    @Override
    public int updateTMineClear(TMineClear tMineClear)
    {
        tMineClear.setUpdateTime(DateUtils.getNowDate());
        return tMineClearMapper.updateTMineClear(tMineClear);
    }

    /**
     * 批量删除排雷记录
     * 
     * @param ids 需要删除的排雷记录主键
     * @return 结果
     */
    @Override
    public int deleteTMineClearByIds(String[] ids)
    {
        return tMineClearMapper.deleteTMineClearByIds(ids);
    }

    /**
     * 删除排雷记录信息
     * 
     * @param id 排雷记录主键
     * @return 结果
     */
    @Override
    public int deleteTMineClearById(String id)
    {
        return tMineClearMapper.deleteTMineClearById(id);
    }

    /**
     * 扫雷统计
     * @param startTime
     * @param endTime
     * @return
     */
    @Override
    public Response<HashMap> count(String startTime, String endTime) {
        /**今日扫雷利润、今日扫雷次数、今日扫雷人数统计*/
        String todaytime = DateUtils.getDate()+" 00:00:00";
        HashMap map = tMineClearMapper.mineClearProfitCount(todaytime,null);

        /**历史扫雷利润、历史扫雷次数、历史扫雷人数统计*/
        HashMap mapa = tMineClearMapper.mineClearProfitCount(startTime,endTime);
        mapa.put("todayProfit",map.get("profit"));
        mapa.put("todayChallengeNum",map.get("challengeNum"));
        mapa.put("todayChallengePersonNum",map.get("challengePersonNum"));
        return Response.success(mapa);
    }

    /**
     * 排雷详情接口
     * @param id
     * @return
     */
    @Override
    public Response<TMineClear> info(String id) {
        TMineClear tMineClear = tMineClearMapper.selectTMineClearById(id);
        List<String> goodsIds = JSONArray.parseArray(tMineClear.getPmineGoods(),String.class);
        List<ChallengeTGoodsVo> tGoods = tGoodsMapper.bacthQueryMineClearTGoodsList(goodsIds.toArray(new String[goodsIds.size()]));
        List<ChallengeTGoodsVo> resultTGoods = new ArrayList<>();
        for (String goodsId : goodsIds) {
            ChallengeTGoodsVo tGoods1 = tGoods.stream().filter(bean -> bean.getGoodsId().equals(goodsId)).findFirst().get();
            resultTGoods.add(tGoods1);
        }
        tMineClear.setGoodsList(resultTGoods);
        List<List<Long>> plateArr = JSON.parseObject(tMineClear.getPlate(), new TypeReference<List<List<Long>>>() {});
        tMineClear.setPlateArr(plateArr);
        return Response.success(tMineClear);
    }

    /**
     * 全名挑战用户展示详情数据
     * @param userId
     * @return
     */
    @Override
    public Response<TMineClear> fullNameChallenge(String userId) {
        try {
            TMineClear tMineClear = null;
            String userprex_isplay = Constants.FULLNAMEUSEISPLAY+userId;
            /**判断该用户是否有进行中的全名挑战*/
            Object obj = redisCache.getCacheObject(userprex_isplay);
            if (obj == null){
                /**表示未有进行中的全名挑战*/
                return this.RefreshTGoods(userId);
            }else {
                List<SysDictData> mineClearGoodsDistribution = iSysDictTypeService.selectDictDataByType("mine_clear_goods_distribution");

                /**表示正在进行全名挑战*/
                tMineClear = tMineClearMapper.getTMineClearByUserIdOn(userId);
                tMineClear.setIsplay(1);
                List<String> goodsIds = JSONArray.parseArray(tMineClear.getPmineGoods(),String.class);
                List<ChallengeTGoodsVo> tGoods = tGoodsMapper.bacthQueryMineClearTGoodsList(goodsIds.toArray(new String[goodsIds.size()]));

                /**获取挑战数据*/
                String userprex = Constants.FULLNAMEUSERKEY+userId;
                String params = redisCache.getCacheObject(userprex).toString();
                RedisChallengeTGoods redisChallengeTGoods = JSON.parseObject(params,RedisChallengeTGoods.class);
                List<ChallengeTGoodsVo> challengeTGoodsVos = redisChallengeTGoods.getChallengeTGoodsVos();

                List<ChallengeTGoodsVo> resultTGoods = new ArrayList<>();
                int layer = 0;
                for (String goodsId : goodsIds) {
                    ChallengeTGoodsVo tGoods1 = tGoods.stream().filter(bean -> bean.getGoodsId().equals(goodsId)).findFirst().get();
                    SysDictData distributionS =  mineClearGoodsDistribution.get(layer);
                    /**排雷分布值*/
                    String[] disarr = distributionS.getDictValue().split("-");
                    tGoods1.setGoodsCnt(Integer.parseInt(disarr[0]));
                    tGoods1.setMineCnt(Integer.parseInt(disarr[1]));
                    layer++;
                    if(CollectionUtils.isNotEmpty(challengeTGoodsVos)){
                        ChallengeTGoodsVo tGoods2 = challengeTGoodsVos.stream().filter(bean -> bean.getGoodsId().equals(goodsId)).findFirst().get();
                        tGoods1.setGoodsPrice(tGoods2.getGoodsPrice());
                    }

                    resultTGoods.add(tGoods1);
                }
                tMineClear.setGoodsList(resultTGoods);
                List<List<Long>> plateArr = JSON.parseObject(tMineClear.getPlate(), new TypeReference<List<List<Long>>>(){});
                tMineClear.setPlateArr(plateArr);
            }
            return Response.success(tMineClear);
        } catch (Exception e) {
            e.printStackTrace();
            log.error("全名挑战列表异常:{}",e.getMessage());
            return Response.fail("请重置");
        }
    }

    /**
     * 刷新全名挑战饰品
     * @param userId
     * @return
     */
    @Override
    public Response<TMineClear> RefreshTGoods(String userId) throws Exception{
        TMineClear tMineClear = new TMineClear();
        List<ChallengeTGoodsVo> goodsList = new ArrayList<>();
        /**获取全名挑战的价格区间档数据*/
        List<SysDictData> priceRangeList =  iSysDictTypeService.selectDictDataByType("full_name_challenge_price_range");
        /**根据概率权重几率获取用户价格档*/
        List<GiftDTO> giftDTOList = new ArrayList<>();
        for (int i = 0; i < priceRangeList.size(); i++) {
            GiftDTO giftDTO = new GiftDTO();
            giftDTO.setIndex(i);
            giftDTO.setNo(priceRangeList.get(i).getDictCode().toString());
            giftDTO.setProbability(Double.parseDouble(priceRangeList.get(i).getDictValue()));
            giftDTOList.add(giftDTO);
        }
        Integer idex = GiftDTO.luckdraw(giftDTOList);
        SysDictData priceRangeSys = priceRangeList.get(idex);
        /**获取最终的价格档*/
        String priceRange = priceRangeSys.getDictLabel();
        /**根据价格档区间随机获取一个价格*/
        double challengeFee = NumRangeUtils.randonPrice(priceRange);

        /**获取所有的全名挑战饰品*/
        List<ChallengeTGoodsVo> allTGoodsVoList = tGoodsMapper.queryAllMineClearTGoodsList();
        /**获取排雷饰品炸弹分布列*/
        List<SysDictData> mineClearGoodsDistribution = iSysDictTypeService.selectDictDataByType("mine_clear_goods_distribution");

        /**判断获取第一关饰品*/
        SysDictData firstDistribution = mineClearGoodsDistribution.stream().filter(bean -> bean.getDictLabel().equals("1")).findFirst().get();
        List<SysDictData> firstLevelFullnameChallenger =  iSysDictTypeService.selectDictDataByType("first_level_fullname_challenger");
        List<GiftDTO> giftDTOList1 = new ArrayList<>();
        for (int i = 0; i < firstLevelFullnameChallenger.size(); i++) {
            GiftDTO giftDTO = new GiftDTO();
            giftDTO.setIndex(i);
            giftDTO.setNo(firstLevelFullnameChallenger.get(i).getDictCode().toString());
            giftDTO.setProbability(Double.parseDouble(firstLevelFullnameChallenger.get(i).getDictValue()));
            giftDTOList1.add(giftDTO);
        }
        Integer idex1 = GiftDTO.luckdraw(giftDTOList1);
        SysDictData firstLevelSysDictData = firstLevelFullnameChallenger.get(idex1);
        String firstlevelPriceRange = firstLevelSysDictData.getDictLabel();
        ChallengeTGoodsVo firstGoods = this.getLevelTGoods(allTGoodsVoList,firstlevelPriceRange,challengeFee,firstDistribution.getDictValue());
        goodsList.add(firstGoods);

        /**第二关-五关饰品价格范围*/
        List<SysDictData> twoFiveLevelFullnameChallenger =  iSysDictTypeService.selectDictDataByType("two_five_level_fullname_challenger");
        /**第二关饰品*/
        SysDictData twoDistribution = mineClearGoodsDistribution.stream().filter(bean -> bean.getDictLabel().equals("2")).findFirst().get();
        SysDictData  twoSysDictData = twoFiveLevelFullnameChallenger.stream().filter(bean -> bean.getDictLabel().equals("2")).findFirst().get();
        String twolevelPriceRange = twoSysDictData.getDictValue();
        ChallengeTGoodsVo twoGoods = this.getLevelTGoods(allTGoodsVoList,twolevelPriceRange,firstGoods.getGoodsPrice(),twoDistribution.getDictValue());
        goodsList.add(twoGoods);

        /**第三关饰品*/
        SysDictData threeDistribution = mineClearGoodsDistribution.stream().filter(bean -> bean.getDictLabel().equals("3")).findFirst().get();
        SysDictData  threeSysDictData = twoFiveLevelFullnameChallenger.stream().filter(bean -> bean.getDictLabel().equals("3")).findFirst().get();
        String threelevelPriceRange = threeSysDictData.getDictValue();
        ChallengeTGoodsVo threeGoods = this.getLevelTGoods(allTGoodsVoList,threelevelPriceRange,twoGoods.getGoodsPrice(),threeDistribution.getDictValue());
        goodsList.add(threeGoods);

        /**第四关饰品*/
        SysDictData fourDistribution = mineClearGoodsDistribution.stream().filter(bean -> bean.getDictLabel().equals("4")).findFirst().get();
        SysDictData  fourSysDictData = twoFiveLevelFullnameChallenger.stream().filter(bean -> bean.getDictLabel().equals("4")).findFirst().get();
        String fourlevelPriceRange = fourSysDictData.getDictValue();
        ChallengeTGoodsVo fourGoods = this.getLevelTGoods(allTGoodsVoList,fourlevelPriceRange,firstGoods.getGoodsPrice(),fourDistribution.getDictValue());
        goodsList.add(fourGoods);

        /**第五关饰品*/
        SysDictData fiveDistribution = mineClearGoodsDistribution.stream().filter(bean -> bean.getDictLabel().equals("5")).findFirst().get();
        SysDictData fiveSysDictData = twoFiveLevelFullnameChallenger.stream().filter(bean -> bean.getDictLabel().equals("5")).findFirst().get();
        String fivelevelPriceRange = fiveSysDictData.getDictValue();
        ChallengeTGoodsVo fiveGoods = this.getLevelTGoods(allTGoodsVoList,fivelevelPriceRange,fourGoods.getGoodsPrice(),fiveDistribution.getDictValue());
        goodsList.add(fiveGoods);

        tMineClear.setChallengeFee(challengeFee);
        tMineClear.setTotalLayer(5);
        tMineClear.setGoodsList(goodsList);
        tMineClear.setIsplay(0);

        SysDictData ss = iSysDictDataService.selectDictDataById(366L);
        String floorsGoodsId=ss.getListClass();
        TGoods bcGoods = tGoodsMapper.selectTGoodsById(floorsGoodsId);
        if (bcGoods == null){
            return Response.fail(Constants.FAILCODE,"请联系管理员,重新设置保底饰品！");
        }
        if (bcGoods.getGoodsPrice().compareTo(new BigDecimal(1)) > 0){
            return Response.fail(Constants.FAILCODE,"保底饰品异常，请联系管理员！");
        }

        String userprex = Constants.FULLNAMEUSERKEY+userId;
        List<String> goodsIds = goodsList.stream().map(ChallengeTGoodsVo::getGoodsId).collect(Collectors.toList());
        RedisChallengeTGoods redisChallengeTGoods = new RedisChallengeTGoods(goodsIds,challengeFee,goodsList,bcGoods.getGoodsPrice().doubleValue());
        redisCache.setCacheObject(userprex,JSON.toJSONString(redisChallengeTGoods));
        return Response.success(tMineClear);
    }

    /**
     * 刷新饰品，随机获取某个饰品
     * @param allTGoodsVoList
     * @param priceRange
     * @return
     */
    public ChallengeTGoodsVo getLevelTGoods(List<ChallengeTGoodsVo> allTGoodsVoList,String priceRange,double goodsPrice,String distribution) throws Exception{
        String[] priceArr = priceRange.split("-");
        double minRadio = Double.parseDouble(priceArr[0]);
        double maxRadio = Double.parseDouble(priceArr[1]);

        double minPrice = Arith.mul(goodsPrice,minRadio,2);
        double maxPrice = Arith.mul(goodsPrice,maxRadio,2);

        try {
            /**饰品*/
            List<ChallengeTGoodsVo> firstGoodsList = allTGoodsVoList.stream().filter(bean -> bean.getGoodsPrice().compareTo(minPrice) >= 0 && bean.getGoodsPrice().compareTo(maxPrice) <= 0).collect(Collectors.toList());
            Collections.shuffle(firstGoodsList);
            ChallengeTGoodsVo tGoodsVo = firstGoodsList.get(0);
            /**排雷分布值*/
            String[] disarr = distribution.split("-");
            tGoodsVo.setGoodsCnt(Integer.parseInt(disarr[0]));
            tGoodsVo.setMineCnt(Integer.parseInt(disarr[1]));
            return tGoodsVo;
        } catch (Exception e) {
            log.error("饰品价值范围:{}  {}-{},{}-{}",goodsPrice,minPrice,maxPrice,minRadio,maxRadio);
            throw new Exception(e.getMessage());
        }
    }

    /**
     * 开始挑战
     * @param userId
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Response<String> startChallenge(String userId) {
        try {
            String whether_show_mine_clearance = sysConfigMapper.checkConfigKeyUnique("whether_show_mine_clearance").getConfigValue();
            if(!Constants.SUCCESS.equals(whether_show_mine_clearance)){
                return Response.fail( "暂未开通全名挑战！");
            }

            TUser tUser = tUserMapper.selectTUserById(userId);
            if (tUser == null || !Constants.SUCCESS.equals(tUser.getDelFlag())) {
                return Response.fail( "用户不存在或已被冻结，请联系管理员！");
            }

            if(tUser.getUserType().equals(Constants.USERTYPE1)){
                String whether_prohibit_anchor_mineclear = sysConfigMapper.checkConfigKeyUnique("whether_prohibit_anchor_mineclear").getConfigValue();
                if(Constants.SUCCESS.equals(whether_prohibit_anchor_mineclear)){
                    return Response.fail( "禁止主播全名挑战！");
                }
            }
            /**判断该用户是否有进行中的全名挑战*/
            String userprex_isplay = Constants.FULLNAMEUSEISPLAY+userId;
            Object obj = redisCache.getCacheObject(userprex_isplay);
            if(obj != null){
                return  Response.fail("已有进行中的挑战！");
            }
            /**获取挑战数据*/
            String userprex = Constants.FULLNAMEUSERKEY+userId;
            String params = redisCache.getCacheObject(userprex).toString();
            RedisChallengeTGoods redisChallengeTGoods = JSON.parseObject(params,RedisChallengeTGoods.class);

            /**新增加饰品价格比对*/
            List<String> goodsIds = redisChallengeTGoods.getGoodsIds();
            if(!CollectionUtils.isEmpty(redisChallengeTGoods.getChallengeTGoodsVos())){
                List<ChallengeTGoodsVo> challengeTGoodsVoList = redisChallengeTGoods.getChallengeTGoodsVos();
                for (ChallengeTGoodsVo vo : challengeTGoodsVoList) {
                    TGoods tGoods = tGoodsMapper.selectTGoodsById(vo.getGoodsId());
                    if(tGoods == null || !Constants.SUCCESS.equals(tGoods.getDelFlag())){
                        return  Response.fail(tGoods.getGoodsName()+" 已下架，请重置！");
                    }
                    Double oldgoodsPrice = vo.getGoodsPrice();
                    if(tGoods.getGoodsPrice().compareTo(BigDecimal.valueOf(oldgoodsPrice)) != 0){
                        return  Response.fail("因饰品价格更新，请重置！");
                    }
                }
            }
            SysDictData ss = iSysDictDataService.selectDictDataById(366L);
            String floorsGoodsId=ss.getListClass();
            TGoods bcGoods = tGoodsMapper.selectTGoodsById(floorsGoodsId);
            if (bcGoods == null){
                return Response.fail(Constants.FAILCODE,"请联系管理员,重新设置保底饰品！");
            }
            if(redisChallengeTGoods.getBdGoodsPrice() != null){
                if(bcGoods.getGoodsPrice().compareTo(BigDecimal.valueOf(redisChallengeTGoods.getBdGoodsPrice())) != 0){
                    return  Response.fail("因保底饰品变更，请重置！");
                }
            }
            /**挑战费用*/
            double challengeFee = redisChallengeTGoods.getChallengeFee();

            /**判断用户余额是否充足*/
            double blance = tUser.getUserBalance().doubleValue();
            if (blance < challengeFee){
                return  Response.fail("余额不足，请充值！");
            };

            /**余额充足，开启挑战*/
            /**插入排雷记录表*/
            TMineClear mineClear = new TMineClear();
            String id = IdUtils.fastSimpleUUID();
            mineClear.setId(id);
            mineClear.setUserId(userId);
            mineClear.setUserType(tUser.getUserType());
            mineClear.setPmineGoods(JSON.toJSONString(redisChallengeTGoods.getGoodsIds()));
            mineClear.setChallengeFee(challengeFee);
            mineClear.setAdoptLayar(0);
            mineClear.setChallengeLayer(1);
            mineClear.setTotalLayer(5);
            mineClear.setPlate(null);
            mineClear.setStatus(Constants.mineStsatus0);
            mineClear.setCreateTime(DateUtils.getNowDate());
            tMineClearMapper.insertTMineClear(mineClear);

            /*用户余额-购买额度>=花费金额 则不变 否则重置为用户余额-花费金额*/
            BigDecimal purchaseQuota = tUser.getPurchaseQuota();
            BigDecimal userBalance = tUser.getUserBalance();
            if (userBalance.subtract(purchaseQuota).compareTo(new BigDecimal(challengeFee)) == -1) {
                tUser.setPurchaseQuota(BigDecimal.valueOf(Arith.sub(blance,challengeFee)));
            }

            /**更新用户余额*/
            tUser.setUserBalance(BigDecimal.valueOf(Arith.sub(blance,challengeFee)));
            int row1 = tUserMapper.updateTUserBalance(tUser);
            if (row1 == 0){
                throw new CustomException("用户余额更新失败");
            }

            /**余额变更记录表*/
            TBalanceChange balanceChange = new TBalanceChange();
            balanceChange.setUserId(userId);
            balanceChange.setBalanceBefore(BigDecimal.valueOf(blance));
            balanceChange.setBalanceAfter(BigDecimal.valueOf(Arith.sub(blance,challengeFee)));
            balanceChange.setOperationType(Constants.OPERATIONTYPE10);
            balanceChange.setFrequency(1);
            balanceChange.setFee(BigDecimal.valueOf(challengeFee));
            balanceChange.setCorrespondingid(id);
            balanceChange.setCreateTime(DateUtils.getNowDate());
            balanceChange.setCzIntegralBefore(tUser.getCzIntegral());
            balanceChange.setCzIntegralAfter(tUser.getCzIntegral());
            balanceChange.setTgIntegralBefore(tUser.getTgIntegral());
            balanceChange.setTgIntegralAfter(tUser.getTgIntegral());
            balanceChangeMapper.insertTBalanceChange(balanceChange);

            /**设置状态*/
            redisCache.setCacheObject(userprex_isplay,1);
            return Response.success("全名挑战成功开启");
        } catch (Exception e) {
            log.error("全名挑战参与异常:{}",e);
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return Response.fail("全名挑战开启失败!");
        }
    }

    /**
     * 开始闯关
     * @param userId
     * @param position
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Response<TMineClear> startAdopt(String userId, int position) {
        try {
            String whether_show_mine_clearance = sysConfigMapper.checkConfigKeyUnique("whether_show_mine_clearance").getConfigValue();
            if(!Constants.SUCCESS.equals(whether_show_mine_clearance)){
                return Response.fail( "暂未开通全名挑战！");
            }

            TUser tUser = tUserMapper.selectTUserById(userId);
            if (tUser == null || !Constants.SUCCESS.equals(tUser.getDelFlag())) {
                return Response.fail( "用户不存在或已被冻结，请联系管理员！");
            }

            if(tUser.getUserType().equals(Constants.USERTYPE1)){
                String whether_prohibit_anchor_mineclear = sysConfigMapper.checkConfigKeyUnique("whether_prohibit_anchor_mineclear").getConfigValue();
                if(Constants.SUCCESS.equals(whether_prohibit_anchor_mineclear)){
                    return Response.fail( "禁止主播全名挑战！");
                }
            }
            TMineClear tMineClear = tMineClearMapper.getTMineClearByUserId(userId,Constants.mineStsatus0);
            if(tMineClear == null){
                return Response.fail("请先开启全名挑战！");
            }
            Double challengeFee = tMineClear.getChallengeFee();
            /**排雷饰品数量分布*/
            List<SysDictData> mineClearGoodsDistribution = iSysDictTypeService.selectDictDataByType("mine_clear_goods_distribution");
            /**全名挑战系数设置*/
            List<SysDictData> fullNameChallengeRatio = null;
            if (tUser.getUserType().equals(Constants.USERTYPE1)){
                fullNameChallengeRatio = iSysDictTypeService.selectDictDataByType("full_name_challenge_ratio_acher");
            }else {
                fullNameChallengeRatio = iSysDictTypeService.selectDictDataByType("full_name_challenge_ratio");
            }

            String pmineGoods = tMineClear.getPmineGoods();
            List<String> goodsIds = JSON.parseArray(pmineGoods,String.class);
            List<ChallengeTGoodsVo> ChallengeTGoodsVos = tGoodsMapper.bacthQueryMineClearTGoodsList(goodsIds.toArray(new String[goodsIds.size()]));
            /**获取挑战数据*/
            String userprex = Constants.FULLNAMEUSERKEY+userId;
            String params = redisCache.getCacheObject(userprex).toString();
            RedisChallengeTGoods redisChallengeTGoods = JSON.parseObject(params,RedisChallengeTGoods.class);
            List<ChallengeTGoodsVo> redisChallengeTGoodsVos = redisChallengeTGoods.getChallengeTGoodsVos();
            /**挑战饰品*/
            List<ChallengeTGoodsVo> challengeTGoodsVos = new ArrayList<>();
            int layer = 0;
            for (String goodsId : goodsIds) {
                ChallengeTGoodsVo tGoods1 = ChallengeTGoodsVos.stream().filter(bean -> bean.getGoodsId().equals(goodsId)).findFirst().get();
                SysDictData distributionS =  mineClearGoodsDistribution.get(layer);
                /**排雷分布值*/
                String[] disarr = distributionS.getDictValue().split("-");
                tGoods1.setGoodsCnt(Integer.parseInt(disarr[0]));
                tGoods1.setMineCnt(Integer.parseInt(disarr[1]));
                if(!CollectionUtils.isEmpty(redisChallengeTGoodsVos)){
                    ChallengeTGoodsVo tGoods2 = redisChallengeTGoodsVos.stream().filter(bean -> bean.getGoodsId().equals(goodsId)).findFirst().get();
                    tGoods1.setGoodsPrice(tGoods2.getGoodsPrice());
                }
                challengeTGoodsVos.add(tGoods1);
                layer++;
            }
            tMineClear.setGoodsList(challengeTGoodsVos);

            /**当前挑战层数和通关层数*/
            int adopt_layar = tMineClear.getAdoptLayar();
            int challenge_layer =tMineClear.getChallengeLayer();
            int total_layer =tMineClear.getTotalLayer();


            /**排雷分布数组*/
            String plate = tMineClear.getPlate();
            List<List<Long>> plateArr = new ArrayList<>();
            if(StringUtils.isNotEmpty(plate)){
                plateArr = JSON.parseObject(plate, new TypeReference<List<List<Long>>>(){});
            }

            /**获取当前层数的炸弹饰品分布个数*/
            SysDictData firstDistribution = mineClearGoodsDistribution.stream().filter(bean -> bean.getDictLabel().equals(challenge_layer+"")).findFirst().get();
            String[] disarr = firstDistribution.getDictValue().split("-");
            int goodsCnt = Integer.parseInt(disarr[0]);
            int mineCnt = Integer.parseInt(disarr[1]);

            if (position >= goodsCnt+mineCnt){
                return Response.fail("选位错误");
            }

            /**获取当前层数的概率系数*/
            SysDictData radioSysDictData = fullNameChallengeRatio.stream().filter(bean -> bean.getDictLabel().equals(challenge_layer+"")).findFirst().get();
            Double radio = Double.parseDouble(radioSysDictData.getDictValue());

            /**计算用户中奖概率*/
            Double winradio = null;
            Double priceradio = null;
            /**判断当前用户所在层数来计算不同的概率算法*/
            if(challenge_layer == 1){ /**第一层*/
                /**挑战费用/第一关饰品价格/第一关系数*/
                priceradio = Arith.div(challengeFee,challengeTGoodsVos.get(challenge_layer-1).getGoodsPrice());
                winradio = Arith.mul(priceradio,radio,4);
            }else {
                /**其他层概率计算*/
                priceradio = Arith.div(challengeTGoodsVos.get(challenge_layer-2).getGoodsPrice(),challengeTGoodsVos.get(challenge_layer-1).getGoodsPrice());
                winradio = Arith.mul(priceradio,radio,4);
            }

            /**判断当前用户是否中奖*/
            List<GiftDTO> giftDTOList = new ArrayList<>();
            GiftDTO giftDTO1 = new GiftDTO();
            giftDTO1.setIndex(0);
            giftDTO1.setNo("0");
            giftDTO1.setProbability(winradio);
            giftDTOList.add(giftDTO1);

            GiftDTO giftDTO2 = new GiftDTO();
            giftDTO2.setIndex(1);
            giftDTO1.setNo("1");
            giftDTO2.setProbability(Arith.sub(Double.parseDouble("1"),winradio));
            giftDTOList.add(giftDTO2);
            int des = GiftDTO.luckdraw(giftDTOList);
            boolean winflage = des == 0 ? true : false;

            /**设置挑战的层级扫雷分布*/
            List<Long> pla = this.plate(position,winflage,goodsCnt,mineCnt);
            plateArr.add(pla);
            tMineClear.setPlate(JSON.toJSONString(plateArr));
            tMineClear.setUpdateTime(DateUtils.getNowDate());

            log.info("全名挑战升级概率：{}，系数：{}，升级成功概率：{}，用户iD：{}, 挑战层数:{},是否通关:{}",priceradio,radio,winradio,userId,challenge_layer,winflage);
            if (winflage){/**表示用户通关该层，可以继续通关*/
                /**判断用户当前关卡是否是最后一关*/
                if(challenge_layer < total_layer){
                    tMineClear.setAdoptLayar(adopt_layar+1);
                    tMineClear.setChallengeLayer(challenge_layer+1);
                    int row1 = tMineClearMapper.updateTMineClear(tMineClear);
                    if(row1 == 0){
                        throw new CustomException("排雷数据更新失败");
                    }
                    tMineClear.setIsplay(1);
                    return Response.success(tMineClear);
                }else {
                    /**插入背包数据*/
                    ChallengeTGoodsVo tGoodsVo = challengeTGoodsVos.get(challengeTGoodsVos.size()-1);
                    /**表示全通关*/
                    tMineClear.setAdoptLayar(total_layer);
                    tMineClear.setChallengeLayer(total_layer);
                    tMineClear.setStatus(Constants.mineStsatus3);

                    /**更新此次排雷数据*/
                    tMineClear.setGoodsId(Long.parseLong(tGoodsVo.getGoodsId()));
                    tMineClear.setGoodsName(tGoodsVo.getGoodsName());
                    tMineClear.setGoodsGrate(tGoodsVo.getGoodsGrate());
                    tMineClear.setGoodsPic(tGoodsVo.getGoodsPic());
                    tMineClear.setGoodsPrice(tGoodsVo.getGoodsPrice().doubleValue());
                    tMineClear.setGoodsType(tGoodsVo.getGoodsType());

                    int row1 = tMineClearMapper.updateTMineClear(tMineClear);
                    if(row1 == 0){
                        throw new CustomException("排雷数据更新失败");
                    }
                    String bbId = DateUtils.dateTimeNow()+ IdUtils.fastUUID().substring(0,8);
                    TBackpack backpack = new TBackpack();
                    backpack.setBbId(bbId);
                    backpack.setUserId(userId);
                    backpack.setGoodsId(tGoodsVo.getGoodsId());
                    backpack.setGoodsBelongingType(Constants.GOOGSBLTYPE10);
                    backpack.setGoodsBelongingId(tGoodsVo.getGoodsId());
                    backpack.setGoodsBelongingName("全名挑战");
                    backpack.setGoodsPrice(BigDecimal.valueOf(tGoodsVo.getGoodsPrice()));
                    backpack.setGoodsExprice(BigDecimal.valueOf(tGoodsVo.getGoodsPrice()));
                    backpack.setBbStatus(Constants.BBSTATUS0);
                    backpack.setDelFlag(Constants.SUCCESS);
                    backpack.setCreateTime(DateUtils.getNowDate());
                    backpack.setGoodsNum(1);
                    backpack.setGoodsType(tGoodsVo.getGoodsType());
                    backpack.setUserPromotersId(tUser.getUserPromotersId());
                    Double openboxPrice = tMineClear.getChallengeFee();
                    if (tMineClear.getRiseFee() != null){
                        openboxPrice = Arith.add(openboxPrice,tMineClear.getRiseFee());
                    }
                    backpack.setOpenBoxPrice(BigDecimal.valueOf(openboxPrice));
                    backpack.setAuditStatus(Constants.AUDITSTATUS0);
                    backpack.setOpenBeforeBalance(tUser.getUserBalance());
                    backpack.setOpenAfterBalance(tUser.getUserBalance());
                    backpack.setBbGoodsName(tGoodsVo.getGoodsName());
                    backpack.setBbGoodsPic(tGoodsVo.getGoodsPic());
                    backpack.setBbGoodsGrate(tGoodsVo.getGoodsGrate());
                    tBackpackMapper.insertTBackpack(backpack);

                    /**清空用户挑战中标注*/
                    String userprex_isplay = Constants.FULLNAMEUSEISPLAY+userId;
                    redisCache.deleteObject(userprex_isplay);
                    tMineClear.setIsplay(0);
                    return Response.success(tMineClear);
                }
            }else { /**表示用户踩雷*/
                boolean endFlag = true;/**是否结束挑战*/
                if (challenge_layer >= 3 && StringUtils.isEmpty(tMineClear.getWhetherRise())){/**如果当前挑战层数是第三关及以上，则根据是否可复活开关来复活调整*/
                    String mineclear_resurrection_switch = sysConfigMapper.checkConfigKeyUnique("mineclear_resurrection_switch").getConfigValue();
                    if ("0".equals(mineclear_resurrection_switch)){
                        endFlag = false;
                    }
                }

                if(endFlag){
                    /**结束挑战*/
                    /**获取全名挑战保底饰品*/
                    SysDictData ss = iSysDictDataService.selectDictDataById(366L);
                    String floorsGoodsId=ss.getListClass();
                    TGoods bcGoods = tGoodsMapper.selectTGoodsById(floorsGoodsId);
                    if (bcGoods == null){
                        return Response.fail(Constants.FAILCODE,"请联系管理员,重新设置保底饰品！");
                    }
                    if(redisChallengeTGoods.getBdGoodsPrice() != null){
                        bcGoods.setGoodsPrice(BigDecimal.valueOf(redisChallengeTGoods.getBdGoodsPrice()));
                    }

                    /**更新此次排雷数据*/
                    tMineClear.setStatus(Constants.mineStsatus1);
                    tMineClear.setGoodsId(Long.parseLong(bcGoods.getGoodsId()));
                    tMineClear.setGoodsName(bcGoods.getGoodsName());
                    tMineClear.setGoodsGrate(bcGoods.getGoodsGrate());
                    tMineClear.setGoodsPic(bcGoods.getGoodsPic());
                    tMineClear.setGoodsPrice(bcGoods.getGoodsPrice().doubleValue());
                    tMineClear.setGoodsType(bcGoods.getGoodsType());

                    for (int i=0;i<challengeTGoodsVos.size();i++){
                        if(i >= adopt_layar+1){
                            List<Long> pla1 = this.waiverPlate(challengeTGoodsVos.get(i).getGoodsCnt(),challengeTGoodsVos.get(i).getMineCnt());
                            plateArr.add(pla1);
                        }
                    }
                    tMineClear.setPlate(JSON.toJSONString(plateArr));
                    int row1 = tMineClearMapper.updateTMineClear(tMineClear);
                    if(row1 == 0){
                        throw new CustomException("排雷数据更新失败");
                    }
                    /**插入背包数据*/
                    String bbId = DateUtils.dateTimeNow()+ IdUtils.fastUUID().substring(0,8);
                    TBackpack backpack = new TBackpack();
                    backpack.setBbId(bbId);
                    backpack.setUserId(userId);
                    backpack.setGoodsId(bcGoods.getGoodsId());
                    backpack.setGoodsBelongingType(bcGoods.getGoodsBelongingType());
                    backpack.setGoodsBelongingId(bcGoods.getGoodsId());
                    backpack.setGoodsBelongingName("全名挑战");
                    backpack.setGoodsPrice(bcGoods.getGoodsPrice());
                    backpack.setGoodsExprice(bcGoods.getGoodsPrice());
                    backpack.setBbStatus(Constants.BBSTATUS0);
                    backpack.setDelFlag(Constants.SUCCESS);
                    backpack.setCreateTime(DateUtils.getNowDate());
                    backpack.setGoodsNum(1);
                    backpack.setGoodsType(bcGoods.getGoodsType());
                    backpack.setUserPromotersId(tUser.getUserPromotersId());
                    Double openboxPrice = tMineClear.getChallengeFee();
                    if (tMineClear.getRiseFee() != null){
                        openboxPrice = Arith.add(openboxPrice,tMineClear.getRiseFee());
                    }
                    backpack.setOpenBoxPrice(BigDecimal.valueOf(openboxPrice));
                    backpack.setAuditStatus(Constants.AUDITSTATUS0);
                    backpack.setOpenBeforeBalance(tUser.getUserBalance());
                    backpack.setOpenAfterBalance(tUser.getUserBalance());
                    backpack.setBbGoodsName(bcGoods.getGoodsName());
                    backpack.setBbGoodsPic(bcGoods.getGoodsPic());
                    backpack.setBbGoodsGrate(bcGoods.getGoodsGrate());
                    tBackpackMapper.insertTBackpack(backpack);

                    /**清空用户挑战中标注*/
                    String userprex_isplay = Constants.FULLNAMEUSEISPLAY+userId;
                    redisCache.deleteObject(userprex_isplay);

                    tMineClear.setIsplay(0);
                }else {
                    /**进入可复活挑战阶段*/
                    tMineClear.setStatus(Constants.mineStsatus4);
                    tMineClear.setWhetherRise("0");
                    int row1 = tMineClearMapper.updateTMineClear(tMineClear);
                    if(row1 == 0){
                        throw new CustomException("排雷数据更新失败");
                    }
                    tMineClear.setIsplay(1);
                }
                return Response.success(tMineClear);
            }
        } catch (NumberFormatException e) {
            log.error("全名挑战闯关异常:{}",e);
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return Response.fail("请重新闯关!");
        }
    }

    /**
     *
     * @param position 所选位置 2
     * @param winflage 是否中奖
     * @param goodsCnt 饰品个数 1
     * @param mineCnt 炸弹个数 0
     * @return
     */
    public  List<Long> plate(int position,boolean winflage,int goodsCnt,int mineCnt){
        List<Long> result = new ArrayList<>();
        int cutnum = goodsCnt+mineCnt;
        if(winflage){
            goodsCnt--;
        }else {
            mineCnt --;
        }
        List<Long> longs = new ArrayList<>();
        for(int i=0;i<goodsCnt;i++){
            longs.add(1l);
        }
        for(int i=0;i<mineCnt;i++){
            longs.add(0l);
        }
        Collections.shuffle(longs);

        for(int i=0;i<cutnum;i++){
            if (i == position){
                if (winflage){
                    result.add(3l);
                }else {
                    result.add(2l);
                }
            }else if(i<position){
                result.add(longs.get(i));
            }else {
                result.add(longs.get(i-1));
            }
        }

        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Response<TMineClear> waiver(String userId) {
        try {
            TUser tUser = tUserMapper.selectTUserById(userId);
            if (tUser == null || !Constants.SUCCESS.equals(tUser.getDelFlag())) {
                return Response.fail("用户不存在或已被冻结，请联系管理员！");
            }
            TMineClear tMineClear = tMineClearMapper.getTMineClearByUserId(userId,Constants.mineStsatus0);
            if(tMineClear == null){
                return Response.fail("请先开启全名挑战！");
            }
            /**当前挑战层数和通关层数*/
            int adopt_layar = tMineClear.getAdoptLayar();
            int challenge_layer =tMineClear.getChallengeLayer();
            int total_layer =tMineClear.getTotalLayer();

            if (adopt_layar == 0){
                return Response.fail("请开始挑战第一层!");
            }

            /**排雷饰品数量分布*/
            List<SysDictData> mineClearGoodsDistribution = iSysDictTypeService.selectDictDataByType("mine_clear_goods_distribution");

            String pmineGoods = tMineClear.getPmineGoods();
            List<String> goodsIds = JSON.parseArray(pmineGoods,String.class);
            List<ChallengeTGoodsVo> tGoods = tGoodsMapper.bacthQueryMineClearTGoodsList(goodsIds.toArray(new String[goodsIds.size()]));

            /**获取挑战数据*/
            String userprex = Constants.FULLNAMEUSERKEY+userId;
            String params = redisCache.getCacheObject(userprex).toString();
            RedisChallengeTGoods redisChallengeTGoods = JSON.parseObject(params,RedisChallengeTGoods.class);
            List<ChallengeTGoodsVo> redisChallengeTGoodsVos = redisChallengeTGoods.getChallengeTGoodsVos();

            /**挑战饰品*/
            List<ChallengeTGoodsVo> challengeTGoodsVos = new ArrayList<>();
            int layer = 0;
            for (String goodsId : goodsIds) {
                ChallengeTGoodsVo tGoods1 = tGoods.stream().filter(bean -> bean.getGoodsId().equals(goodsId)).findFirst().get();
                SysDictData distributionS =  mineClearGoodsDistribution.get(layer);
                /**排雷分布值*/
                String[] disarr = distributionS.getDictValue().split("-");
                tGoods1.setGoodsCnt(Integer.parseInt(disarr[0]));
                tGoods1.setMineCnt(Integer.parseInt(disarr[1]));

                if(!CollectionUtils.isEmpty(redisChallengeTGoodsVos)){
                    ChallengeTGoodsVo tGoods2 = redisChallengeTGoodsVos.stream().filter(bean -> bean.getGoodsId().equals(goodsId)).findFirst().get();
                    tGoods1.setGoodsPrice(tGoods2.getGoodsPrice());
                }

                challengeTGoodsVos.add(tGoods1);
                layer++;
            }
            tMineClear.setGoodsList(challengeTGoodsVos);
            ChallengeTGoodsVo tGoodsVo = challengeTGoodsVos.get(adopt_layar-1);
            tMineClear.setStatus(Constants.mineStsatus2);
            tMineClear.setGoodsId(Long.parseLong(tGoodsVo.getGoodsId()));
            tMineClear.setGoodsName(tGoodsVo.getGoodsName());
            tMineClear.setGoodsGrate(tGoodsVo.getGoodsGrate());
            tMineClear.setGoodsPic(tGoodsVo.getGoodsPic());
            tMineClear.setGoodsPrice(tGoodsVo.getGoodsPrice().doubleValue());
            tMineClear.setGoodsType(tGoodsVo.getGoodsType());
            tMineClear.setUpdateTime(DateUtils.getNowDate());

            /**排雷分布数组*/
            String plate = tMineClear.getPlate();
            List<List<Long>> plateArr = new ArrayList<>();
            if(StringUtils.isNotEmpty(plate)){
                plateArr = JSON.parseObject(plate, new TypeReference<List<List<Long>>>(){});
            }
            for (int i=0;i<challengeTGoodsVos.size();i++){
                if(i >= adopt_layar){
                    List<Long> pla = this.waiverPlate(challengeTGoodsVos.get(i).getGoodsCnt(),challengeTGoodsVos.get(i).getMineCnt());
                    plateArr.add(pla);
                }
            }
            tMineClear.setPlate(JSON.toJSONString(plateArr));
            int row1 = tMineClearMapper.updateTMineClear(tMineClear);
            if(row1 == 0){
                throw new CustomException("排雷数据更新失败");
            }
            /**插入背包数据*/
            String bbId = DateUtils.dateTimeNow()+ IdUtils.fastUUID().substring(0,8);
            TBackpack backpack = new TBackpack();
            backpack.setBbId(bbId);
            backpack.setUserId(userId);
            backpack.setGoodsId(tGoodsVo.getGoodsId());
            backpack.setGoodsBelongingType(Constants.GOOGSBLTYPE10);
            backpack.setGoodsBelongingId(tGoodsVo.getGoodsId());
            backpack.setGoodsBelongingName("全名挑战");
            backpack.setGoodsPrice(BigDecimal.valueOf(tGoodsVo.getGoodsPrice()));
            backpack.setGoodsExprice(BigDecimal.valueOf(tGoodsVo.getGoodsPrice()));
            backpack.setBbStatus(Constants.BBSTATUS0);
            backpack.setDelFlag(Constants.SUCCESS);
            backpack.setCreateTime(DateUtils.getNowDate());
            backpack.setGoodsNum(1);
            backpack.setGoodsType(tGoodsVo.getGoodsType());
            backpack.setUserPromotersId(tUser.getUserPromotersId());
            backpack.setOpenBoxPrice(BigDecimal.valueOf(tMineClear.getChallengeFee()));
            backpack.setAuditStatus(Constants.AUDITSTATUS0);
            backpack.setOpenBeforeBalance(tUser.getUserBalance());
            backpack.setOpenAfterBalance(tUser.getUserBalance());
            backpack.setBbGoodsName(tGoodsVo.getGoodsName());
            backpack.setBbGoodsPic(tGoodsVo.getGoodsPic());
            backpack.setBbGoodsGrate(tGoodsVo.getGoodsGrate());
            tBackpackMapper.insertTBackpack(backpack);

            /**清空用户挑战中标注*/
            String userprex_isplay = Constants.FULLNAMEUSEISPLAY+userId;
            redisCache.deleteObject(userprex_isplay);

            tMineClear.setIsplay(0);
            return Response.success(tMineClear);
        } catch (NumberFormatException e) {
            log.error("全名挑战闯关异常:{}",e);
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return Response.fail("请重新闯关!");
        }
    }


    public  List<Long> waiverPlate(int goodsCnt,int mineCnt){
        List<Long> longs = new ArrayList<>();
        for(int i=0;i<goodsCnt;i++){
            longs.add(1l);
        }
        for(int i=0;i<mineCnt;i++){
            longs.add(0l);
        }
        Collections.shuffle(longs);
        return longs;
    }

    /**
     * 是否复活挑战
     * @param userId
     * @param type
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Response<TMineClear> riseChallenge(String userId, String type) {
        TUser tUser = tUserMapper.selectTUserById(userId);
        if (tUser == null || !Constants.SUCCESS.equals(tUser.getDelFlag())) {
            return Response.fail("用户不存在或已被冻结，请联系管理员！");
        }
        TMineClear tMineClear = tMineClearMapper.getTMineClearByUserId(userId,Constants.mineStsatus4);
        if(tMineClear == null){
            return Response.fail("请先开启全名挑战！");
        }
        /**当前挑战层数和通关层数*/
        int adopt_layar = tMineClear.getAdoptLayar();
        int challenge_layer =tMineClear.getChallengeLayer();
        int total_layer =tMineClear.getTotalLayer();

        boolean flag = true;/**默认复活*/
        if (!"0".equals(type)){
            flag = false;
        }

        /**排雷饰品数量分布*/
        List<SysDictData> mineClearGoodsDistribution = iSysDictTypeService.selectDictDataByType("mine_clear_goods_distribution");

        String pmineGoods = tMineClear.getPmineGoods();
        List<String> goodsIds = JSON.parseArray(pmineGoods,String.class);
        List<ChallengeTGoodsVo> tGoods = tGoodsMapper.bacthQueryMineClearTGoodsList(goodsIds.toArray(new String[goodsIds.size()]));

        /**获取挑战数据*/
        String userprex = Constants.FULLNAMEUSERKEY+userId;
        String params = redisCache.getCacheObject(userprex).toString();
        RedisChallengeTGoods redisChallengeTGoods = JSON.parseObject(params,RedisChallengeTGoods.class);
        List<ChallengeTGoodsVo> redisChallengeTGoodsVos = redisChallengeTGoods.getChallengeTGoodsVos();

        /**挑战饰品*/
        List<ChallengeTGoodsVo> challengeTGoodsVos = new ArrayList<>();
        int layer = 0;
        for (String goodsId : goodsIds) {
            ChallengeTGoodsVo tGoods1 = tGoods.stream().filter(bean -> bean.getGoodsId().equals(goodsId)).findFirst().get();
            SysDictData distributionS =  mineClearGoodsDistribution.get(layer);
            /**排雷分布值*/
            String[] disarr = distributionS.getDictValue().split("-");
            tGoods1.setGoodsCnt(Integer.parseInt(disarr[0]));
            tGoods1.setMineCnt(Integer.parseInt(disarr[1]));
            if(!CollectionUtils.isEmpty(redisChallengeTGoodsVos)){
                ChallengeTGoodsVo tGoods2 = redisChallengeTGoodsVos.stream().filter(bean -> bean.getGoodsId().equals(goodsId)).findFirst().get();
                tGoods1.setGoodsPrice(tGoods2.getGoodsPrice());
            }
            challengeTGoodsVos.add(tGoods1);
            layer++;
        }
        tMineClear.setGoodsList(challengeTGoodsVos);
        /**排雷分布数组*/
        String plate = tMineClear.getPlate();
        List<List<Long>> plateArr = new ArrayList<>();
        if(StringUtils.isNotEmpty(plate)){
            plateArr = JSON.parseObject(plate, new TypeReference<List<List<Long>>>(){});
        }

        if (flag){
            /**复活挑战，支付挑战层的上一层饰品费用*/
            Double riseFee = challengeTGoodsVos.get(challenge_layer-2).getGoodsPrice();
            /**判断用户余额是否充足*/
            double blance = tUser.getUserBalance().doubleValue();
            if (blance < riseFee){
                return  Response.fail("余额不足，请充值！");
            };

            /**余额充足、复活挑战*/
            tMineClear.setStatus(Constants.mineStsatus0);
            tMineClear.setRiseFee(riseFee);
            tMineClear.setRiseLayer(challenge_layer);
            tMineClear.setRiseTime(DateUtils.getNowDate());
            /**清除当前层数的饰品分布*/
            plateArr.remove(challenge_layer-1);
            tMineClear.setPlateArr(plateArr);
            tMineClear.setPlate(JSON.toJSONString(plateArr));
            int row1 = tMineClearMapper.updateTMineClear(tMineClear);
            if(row1 == 0){
                throw new CustomException("排雷数据更新失败");
            }

            /*用户余额-购买额度>=花费金额 则不变 否则重置为用户余额-花费金额*/
            BigDecimal purchaseQuota = tUser.getPurchaseQuota();
            BigDecimal userBalance = tUser.getUserBalance();
            if (userBalance.subtract(purchaseQuota).compareTo(new BigDecimal(riseFee)) == -1) {
                tUser.setPurchaseQuota(BigDecimal.valueOf(Arith.sub(blance,riseFee)));
            }
            /**更新用户余额*/
            tUser.setUserBalance(BigDecimal.valueOf(Arith.sub(blance,riseFee)));
            int row2 = tUserMapper.updateTUserBalance(tUser);
            if (row2 == 0){
                throw new CustomException("用户余额更新失败");
            }

            /**余额变更记录表*/
            TBalanceChange balanceChange = new TBalanceChange();
            balanceChange.setUserId(userId);
            balanceChange.setBalanceBefore(BigDecimal.valueOf(blance));
            balanceChange.setBalanceAfter(BigDecimal.valueOf(Arith.sub(blance,riseFee)));
            balanceChange.setOperationType(Constants.OPERATIONTYPE10);
            balanceChange.setFrequency(1);
            balanceChange.setFee(BigDecimal.valueOf(riseFee));
            balanceChange.setCorrespondingid(tMineClear.getId());
            balanceChange.setCreateTime(DateUtils.getNowDate());
            balanceChange.setCzIntegralBefore(tUser.getCzIntegral());
            balanceChange.setCzIntegralAfter(tUser.getCzIntegral());
            balanceChange.setTgIntegralBefore(tUser.getTgIntegral());
            balanceChange.setTgIntegralAfter(tUser.getTgIntegral());
            balanceChangeMapper.insertTBalanceChange(balanceChange);

            tMineClear.setIsplay(1);
        }else {
            /**放弃复活*/
            /**获取全名挑战保底饰品*/
            SysDictData ss = iSysDictDataService.selectDictDataById(366L);
            String floorsGoodsId=ss.getListClass();
            TGoods bcGoods = tGoodsMapper.selectTGoodsById(floorsGoodsId);
            if (bcGoods == null){
                return Response.fail(Constants.FAILCODE,"请联系管理员,重新设置保底饰品！");
            }
            if(redisChallengeTGoods.getBdGoodsPrice() != null){
                bcGoods.setGoodsPrice(BigDecimal.valueOf(redisChallengeTGoods.getBdGoodsPrice()));
            }

            /**更新此次排雷数据*/
            tMineClear.setStatus(Constants.mineStsatus1);
            tMineClear.setGoodsId(Long.parseLong(bcGoods.getGoodsId()));
            tMineClear.setGoodsName(bcGoods.getGoodsName());
            tMineClear.setGoodsGrate(bcGoods.getGoodsGrate());
            tMineClear.setGoodsPic(bcGoods.getGoodsPic());
            tMineClear.setGoodsPrice(bcGoods.getGoodsPrice().doubleValue());
            tMineClear.setGoodsType(bcGoods.getGoodsType());

            for (int i=0;i<challengeTGoodsVos.size();i++){
                if(i >= adopt_layar+1){
                    List<Long> pla1 = this.waiverPlate(challengeTGoodsVos.get(i).getGoodsCnt(),challengeTGoodsVos.get(i).getMineCnt());
                    plateArr.add(pla1);
                }
            }
            tMineClear.setPlateArr(plateArr);
            tMineClear.setPlate(JSON.toJSONString(plateArr));
            int row1 = tMineClearMapper.updateTMineClear(tMineClear);
            if(row1 == 0){
                throw new CustomException("排雷数据更新失败");
            }
            /**插入背包数据*/
            String bbId = DateUtils.dateTimeNow()+ IdUtils.fastUUID().substring(0,8);
            TBackpack backpack = new TBackpack();
            backpack.setBbId(bbId);
            backpack.setUserId(userId);
            backpack.setGoodsId(bcGoods.getGoodsId());
            backpack.setGoodsBelongingType(bcGoods.getGoodsBelongingType());
            backpack.setGoodsBelongingId(bcGoods.getGoodsId());
            backpack.setGoodsBelongingName("全名挑战");
            backpack.setGoodsPrice(bcGoods.getGoodsPrice());
            backpack.setGoodsExprice(bcGoods.getGoodsPrice());
            backpack.setBbStatus(Constants.BBSTATUS0);
            backpack.setDelFlag(Constants.SUCCESS);
            backpack.setCreateTime(DateUtils.getNowDate());
            backpack.setGoodsNum(1);
            backpack.setGoodsType(bcGoods.getGoodsType());
            backpack.setUserPromotersId(tUser.getUserPromotersId());
            backpack.setOpenBoxPrice(BigDecimal.valueOf(tMineClear.getChallengeFee()));
            backpack.setAuditStatus(Constants.AUDITSTATUS0);
            backpack.setOpenBeforeBalance(tUser.getUserBalance());
            backpack.setOpenAfterBalance(tUser.getUserBalance());
            backpack.setBbGoodsName(bcGoods.getGoodsName());
            backpack.setBbGoodsPic(bcGoods.getGoodsPic());
            backpack.setBbGoodsGrate(bcGoods.getGoodsGrate());
            tBackpackMapper.insertTBackpack(backpack);

            /**清空用户挑战中标注*/
            String userprex_isplay = Constants.FULLNAMEUSEISPLAY+userId;
            redisCache.deleteObject(userprex_isplay);

            tMineClear.setIsplay(0);
        }
        return Response.success(tMineClear);
    }

    /**
     * 扫雷排名
     * @param type
     * @param userId
     * @return
     */
    @Override
    public Map mineClearRanking(String type, String userId) {
        if(type.equalsIgnoreCase("today")){
            type = "0";
        }else {
            type = "1";
        }
        Map map = new HashMap();
        List<TUserRank> tUserRanks = tMineClearMapper.mineClearRanking(type);
        TUserRank tUserRank = null;
        if (StringUtils.isNotEmpty(userId) && tUserRanks.size()>0){
            TUser tUser = tUserMapper.selectTUserById(userId);
            if(tUser.getUserType().equals(Constants.USERTYPE0)){
                /**判断当前用户*/
                List<TUserRank> tUserRanks1 = tUserRanks.stream().filter(bean -> bean.getUserId().equals(userId)).collect(Collectors.toList());
                if(tUserRanks1.size()>0){
                    tUserRank = tUserRanks1.get(0);
                    tUserRank.setUserId(null);
                }
            }
        }
        if(tUserRanks.size()>0){
            int num = tUserRanks.size()>=10 ? 10 : tUserRanks.size();
            tUserRanks = tUserRanks.subList(0,num);
            for (TUserRank userRank : tUserRanks) {
                userRank.setUserId(null);
            }
        }
        map.put("list",tUserRanks);
        map.put("user",tUserRank);
        return map;
    }

}
